﻿using System;
using System.IO;
using System.Text;
using Newtonsoft.Json.Linq;
using System.ComponentModel;
using System.Collections.Generic;
using System.Net;
using System.Drawing;
using Newtonsoft.Json;
using System.Windows.Forms;
using CoreShop.Model;
using System.Diagnostics;
using CoreShop.Model.FromBody;

namespace CoreShop.Library
{
    /// <summary>
    /// 创智链ai操作类
    /// </summary>
    public class LxxAIBusiness
    {
        string url = $"{GlobalConstVars.AIData.LxxAiUrl}:{GlobalConstVars.AIData.LxxAiPort}";


        ///// <summary>
        ///// 启动进程
        ///// </summary>
        public void StartProcess()
        {
            try
            {
                // 进程已接收到结束时就不要再启动了
                //if (exited) return;

                //启动参数可以加一个 -daemon 保证主程序异常退出我们能正常运行，不会线程卡死。

                // 记录参数
                string args = $" -daemon -port {GlobalConstVars.AIData.LxxAiPort} -vc {GlobalConstVars.AIData.VendorCode} -vk {GlobalConstVars.AIData.VendorKey}";

                // 创建一个进程启动信息实例
                ProcessStartInfo startInfo = new ProcessStartInfo
                {
                    // 可执行文件路径
                    FileName = $"{GlobalConstVars.APP_BASEDIRECTORY}\\{GlobalConstVars.AIData.LxxAIPath}{GlobalConstVars.AIData.LxxSdkFile}",
                    // 启动参数
                    Arguments = args,
                    // 是否需要启动shell窗口
                    UseShellExecute = false,
                    // 是否在无窗口启动该进程
                    CreateNoWindow = true,
                    // 是否重定向输入
                    //RedirectStandardInput = false,
                    // 是否重定向输出
                    //RedirectStandardOutput = false,
                    // 是否重定向错误
                    RedirectStandardError = true,
                    // 输出内容编码
                    //StandardOutputEncoding = System.Text.Encoding.UTF8,
                    // 错误内容编码
                    StandardErrorEncoding = System.Text.Encoding.UTF8,
                    // 指定进程的工作路径
                    WorkingDirectory = $"{GlobalConstVars.APP_BASEDIRECTORY}\\{GlobalConstVars.AIData.LxxAIPath}"
                };
                //设置环境变量
                startInfo.EnvironmentVariables.Add("GO_I18N_CODE", "zh-cn");
                // 创建一个进程实例
                Process process = new Process
                {
                    StartInfo = startInfo,
                };

                // 启动进程
                bool ok = process.Start();
                if (!ok)
                {
                    // 进程启动失败，重新启动进程
                    LogManager.WriteTxtLog("sanqingniaosdk process start failed, process.Start() == false");
                    return;
                }

                // 接收重定向的输出信息
                process.OutputDataReceived += (s, e) =>
                {
                    LogManager.WriteTxtLog($"sanqingniaosdk process standard output message: {e.Data}");
                };

                // 接收重定向的错误信息
                process.ErrorDataReceived += (s, e) =>
                {
                    //if (!exited)
                    //{
                    //    LogManager.WriteTxtLog($"sanqingniaosdk process standard error message: {e.Data}");
                    //}
                };

                // 通知重定向错误信息开始
                //process.BeginOutputReadLine();
                process.BeginErrorReadLine();

                // 创建客户端连接
                //ok = ConnectGrpcChannel(aiProcessParameter.Port);
                //if (!ok)
                //{
                //    // 连接失败了，关闭进程，重新启动进程
                //    process.Close();
                //    return;
                //}

                // AI进程运行成功
                LogManager.WriteTxtLog("sanqingniaosdk process running···");

                // 等待进程结束，重新启动进程
                process.WaitForExit();
                LogManager.WriteTxtLog($"sanqingniaosdk process exited, exit code: {process.ExitCode}");
            }
            catch (Exception e)
            {
                // 记录到日志中，重新启动进程
                LogManager.WriteTxtLog($"sanqingniaosdk process exited, exception message: {e}");
            }
        }

        /// <summary>
        /// 关闭AI程序
        /// </summary>
        public int ExistsProcess()
        {
            // 使用进程名称（不带.exe）
            string fileName = GlobalConstVars.AIData.LxxSdkFile.Replace(".exe", string.Empty);
            Process[] processes = Process.GetProcessesByName(fileName);
            return processes.Length;
        }

        ///// <summary>
        ///// 停止进程
        ///// </summary>
        public void StopProcess()
        {
            DialogTool.ApplicationKill(GlobalConstVars.AIData.LxxSdkFile.Replace(".exe", string.Empty));
        }


        /// <summary>
        /// 获取激活状态
        /// </summary>
        /// <returns></returns>
        public LxxDeviceInfoModel GetDeviceInfo()
        {
            try
            {
                var request = WebRequest.Create(url + "/rpc/device/get/info");
                request.Method = "POST";
                var response = (HttpWebResponse)request.GetResponse();

                string content;
                using (var sr = new StreamReader(response.GetResponseStream()))
                {
                    content = sr.ReadToEnd();
                }

                ApiReturnModel apiReturnModel = content.JsonToEntity<ApiReturnModel>();
                if (apiReturnModel != null && apiReturnModel.data != null)
                {
                    string msg = apiReturnModel.msg;
                    LxxDeviceInfoModel lxxDeviceInfo = apiReturnModel.data.ToString().JsonToEntity<LxxDeviceInfoModel>();
                    lxxDeviceInfo.code = apiReturnModel.code;
                    return lxxDeviceInfo;
                }
            }
            catch
            {

            }
            return null;
        }

        /// <summary>
        /// 获取连接状态
        /// </summary>
        /// <returns></returns>
        public string GetConnectState(ref bool isConnect)
        {
            try
            {
                string content = "";
                // 连接AI
                var request = WebRequest.Create(url + "/rpc/get/version");
                request.Method = "POST";
                var response = (HttpWebResponse)request.GetResponse();
                using (var sr = new StreamReader(response.GetResponseStream()))
                {
                    content = sr.ReadToEnd();
                }
                var status = JObject.Parse(content);
                if ((status.GetValue("code").ToString() == "1") && (status.GetValue("msg").ToString() == "success"))
                {
                    isConnect = true;
                    return "已连接";
                }
            }
            catch (Exception ex)
            {

            }
            return "连接失败.";
        }


        /// <summary>
        /// 获取拍图
        /// </summary>
        /// <returns></returns>
        public Image GetCameraImg()
        {
            Image result = null;
            String exceptionText = "";
            try
            {
                //var request = WebRequest.Create(url + "/predict-product-names");
                var request = WebRequest.Create(url + "/rpc/camera/frame");
                request.Method = "GET";
                var response = (HttpWebResponse)request.GetResponse();
                Stream str = response.GetResponseStream();
                result = Image.FromStream(str);
                GC.Collect();
            }
            catch (Exception ex)
            {
                exceptionText = ex.ToString();
                //A_SetLog(" 错误号：Czl_GetCameraImg:" + ex.Message);
            }
            return result;
        }

        /// <summary>
        /// 清空学习数据
        /// </summary>
        /// <returns></returns>
        public bool SetLearnDataClear()
        {
            try
            {
                string content = "";
                // 连接AI
                var request = WebRequest.Create(url + "/rpc/learn/data/clear");
                request.Method = "POST";
                var response = (HttpWebResponse)request.GetResponse();
                using (var sr = new StreamReader(response.GetResponseStream()))
                {
                    content = sr.ReadToEnd();
                }
                var status = JObject.Parse(content);
                if ((status.GetValue("code").ToString() == "1") && (status.GetValue("msg").ToString() == "success"))
                {
                    return true;
                }                
            }
            catch (Exception ex)
            {

            }
            return false;
        }
        


        /// <summary>
        /// 发送AI识别(深圳创智链chuangzhilian)
        /// </summary>
        public LxxMatchingResultModel GetProducts()
        {
            LxxMatchingResultModel lxxMatchingModel = new LxxMatchingResultModel();
            try
            {
                var request = WebRequest.Create(url + "/rpc/ai/unsafe/matching");
                request.Method = "POST";
                var payload = new JObject();
                payload["weight"] = 1000;
                payload["status"] = 0;

                using (Stream requestStream = request.GetRequestStream())
                {
                    byte[] buffer = System.Text.Encoding.UTF8.GetBytes(payload.ToString());
                    requestStream.Write(buffer, 0, buffer.Length);
                }
                var response = (HttpWebResponse)request.GetResponse();

                string content;
                using (var sr = new StreamReader(response.GetResponseStream()))
                {
                    content = sr.ReadToEnd();
                }

                ApiReturnModel apiReturnModel = content.JsonToEntity<ApiReturnModel>();
                if (apiReturnModel != null && apiReturnModel.data != null && (apiReturnModel.code == 1))
                {
                    lxxMatchingModel.msg = "成功";
                    GetMatchingResultModel getMatchingModel = apiReturnModel.data.ToString().JsonToEntity<GetMatchingResultModel>();
                    lxxMatchingModel.skuList = getMatchingModel.skuList.ToString().JsonToEntity<List<LxxLearningSkuModel>>();                                      

                    lxxMatchingModel.id = getMatchingModel.id;
                    return lxxMatchingModel;
                }
            }
            catch
            {
                lxxMatchingModel.msg = "异常";
            }            
            return lxxMatchingModel;
        }

        /// <summary>
        /// 学习(深圳创智链chuangzhilian)
        /// </summary>
        public void SetFeedback(LxxLearningModel learningModel)
        {
            try
            {
                var request = WebRequest.Create(url + "/rpc/ai/learning");
                request.ContentType = "application/json";
                request.Method = "POST";
                using (Stream requestStream = request.GetRequestStream())
                {
                    string mjson = JsonConvert.SerializeObject(learningModel);
                    byte[] buffer = System.Text.Encoding.UTF8.GetBytes(mjson);
                    requestStream.Write(buffer, 0, buffer.Length);
                }
                var response = (HttpWebResponse)request.GetResponse();

                string content = response.StatusCode.ToString();
                using (var sr = new StreamReader(response.GetResponseStream()))
                {
                    content = sr.ReadToEnd();
                }             
            }
            catch (WebException e)
            {
                using (WebResponse response = e.Response)
                {
                    HttpWebResponse httpResponse = (HttpWebResponse)response;
                    if (httpResponse !=null)
                    {
                        Console.WriteLine("Error code: {0}", httpResponse.StatusCode);
                        using (Stream data = response.GetResponseStream())
                        using (var reader = new StreamReader(data))
                        {
                            string text = reader.ReadToEnd();
                            Console.WriteLine(text);
                        }
                    }
                }
                //Log.LogManage.Error("学习(深圳创智链chuangzhilian)错误" + e.Message);
            }
        }
                
        ///// <summary>
        ///// 设置识别区域
        ///// </summary>
        ///// <returns></returns>
        public string ShowCameraAreaView()
        {
            return HttpHelper.GetSendMessage(url,"/grpc/show/camera/area", timeout: 60).MessageOrString;
        }

        ///// <summary>
        ///// 将商品上传
        ///// </summary>
        ///// <returns></returns>
        public string PluSync(List<JObject> keyValuePairs)
        {
            //主体
            JObject keyValues = new JObject();

            keyValues.Add(new JProperty("pluList", keyValuePairs));

            return HttpHelper.PostSendMessage(url,"/grpc/plu/sync", keyValues.ToJsonString(), timeout: 60).MessageOrString;
        }

        
        ///// <summary>
        ///// 标记学习接口
        ///// </summary>
        ///// <returns></returns>
        public string Mark(string code, string name, string identifyID)
        {
            JObject keyValues = new JObject();
            JObject keyValuesPlu = new JObject();

            keyValuesPlu.Add(new JProperty("code", code));
            keyValuesPlu.Add(new JProperty("name", name));
            keyValues.Add(new JProperty("identifyID", identifyID));
            keyValues.Add(new JProperty("markType", 2));

            keyValues.Add("plu", keyValuesPlu);

            return HttpHelper.PostSendMessage(url,"/grpc/ai/mark",
                keyValues.ToJsonString(), timeout: 60).MessageOrString;
        }

        ///// <summary>
        ///// 获取激活码
        ///// </summary>
        ///// <returns></returns>
        public ReturnModel GetActivateCode()
        {
            JObject keyValues = new JObject();
            return null;
            //keyValues.Add(new JProperty("branchId", InitDataModel.StaticData.userInfoData.data.baseDeviceBranchDto.branchId));
            //keyValues.Add(new JProperty("deviceNo", InitDataModel.StaticData.MacAddress));

            //return BusTool.httpTool.PostSendMessage(InitDataModel.StaticData.ApiUrl,
            //      $"{StaticStringTool.SERVER.BASE}{StaticStringTool.API.BASE_PARAM_FEIGN_GETBASEAIBIND}", keyValues.ToJsonString());
        }
    }
}
